//
//  LBXDownLoadOperation.m
//  LBXKit
//
//  Created by lbx on 2017/11/6.
//  Copyright © 2017年 lbx. All rights reserved.
//

#import "LBXDownLoadOperation.h"
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "LBXDownLoadItem.h"
#import "NSURLSessionTask+LBXDownLoadItem.h"
#import "NSURLSession+CorrectedResumeData.h"
//#import "LBX.h"

//超时时间
static  NSTimeInterval downLoadTimeoutInterval = 60.0;

#pragma mark- 下载操作

@interface LBXDownLoadOperation()
@property (nonatomic, strong) NSURLSessionDownloadTask *downLoadTask;

@property (nonatomic, weak) NSURLSession *session;
@property (nonatomic, weak)  LBXDownLoadItem *item;
@end

@implementation LBXDownLoadOperation


- (instancetype)initWithItem:(LBXDownLoadItem*)item session:(NSURLSession*)session
{
    if (self = [super init]) {
        self.item = item;
        self.session = session;
       
        [self startRequest];
    }
    return self;
}

- (instancetype)initWithItem:(LBXDownLoadItem*)item session:(NSURLSession*)session request:(NSURLRequest*)request
{
    if (self = [super init]) {
        self.item = item;
        self.session = session;
        [self startWithRequest:request];
    }
    return self;
}

- (void)dealloc
{
    [self cancel];
}

- (void)startRequest
{
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:_item.remoteURL]
                                                  cachePolicy:NSURLRequestUseProtocolCachePolicy
                                              timeoutInterval:downLoadTimeoutInterval];
    [self startWithRequest:request];
}

- (void)startWithRequest:(NSURLRequest*)request
{
    if (self.item.resumeData)
    {
//        if (@available(iOS 11,*)) {
//            self.downLoadTask = [self.session downloadTaskWithCorrectResumeData:self.item.resumeData];
//        }
//        else
        {
            self.downLoadTask = [self.session downloadTaskWithResumeData:self.item.resumeData];
        }
    }
    else
    {
        self.downLoadTask = [self.session downloadTaskWithRequest:request];
    }
    
    NSLog(@"taskIdentifer:%lu",(unsigned long)self.downLoadTask.taskIdentifier);
        
    self.downLoadTask.lbx_downLoadItem = self.item;
    
    self.item.taskIdentifier = self.downLoadTask.taskIdentifier;
    self.downLoadTask.taskDescription = self.item.taskDescription;
}


- (void)setDownLoadTask:(NSURLSessionDownloadTask *)downLoadTask
{
    if (_downLoadTask) {
        [_downLoadTask removeObserver:self forKeyPath:@"state"];
    }
    _downLoadTask = downLoadTask;
    
    if (_downLoadTask) {
        [_downLoadTask addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial |NSKeyValueObservingOptionOld context:nil];
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (self.item)
    {
        switch (self.downLoadTask.state)
        {
            case NSURLSessionTaskStateRunning:
                self.item.status = LBXDownloadStatus_Running;
                return;
                break;
            case NSURLSessionTaskStateSuspended:
                self.item.status = LBXDownloadStatus_Suspended;
                return;
                break;
            case NSURLSessionTaskStateCompleted:
                //任务结束:有可能下载完成，也有可能下载失败导致
            {
                
            }
                break;
            case NSURLSessionTaskStateCanceling:
            {
                //任务取消
            }
                break;
            default:
                break;
        }
    }
}

#pragma mark-  状态

- (void)start
{
    [self resume];
}

- (void)suspend
{
    if (self.downLoadTask)
    {
        switch (self.downLoadTask.state) {
            case NSURLSessionTaskStateRunning:
            {
                __weak __typeof(self) weakSelf = self;
                [self.downLoadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
                    if (resumeData) {
//                      NSLog(@"resumedata len1:%ld",resumeData.length);
                        weakSelf.item.resumeData = resumeData;
                    }
                }];
                [self.downLoadTask suspend];
                return;
            }
                break;
            case NSURLSessionTaskStateSuspended:
                self.item.status = LBXDownloadStatus_Suspended;
                break;
            case NSURLSessionTaskStateCompleted:
            case NSURLSessionTaskStateCanceling:
                self.item.status = LBXDownloadStatus_Suspended;
                self.downLoadTask.lbx_downLoadItem = nil;
                self.downLoadTask = nil;
                break;
            default:
                break;
        }
    }
    else{
        self.item.status = LBXDownloadStatus_Suspended;
    }
}

- (void)resume
{
    if (self.downLoadTask) {
        
        switch (self.downLoadTask.state) {
            case NSURLSessionTaskStateRunning:
            {
                self.item.status = LBXDownloadStatus_Running;
                return;
            }
                break;
            case NSURLSessionTaskStateSuspended:
            {
                [self.downLoadTask resume];
                return;
            }
                break;
            case NSURLSessionTaskStateCompleted:
            case NSURLSessionTaskStateCanceling:
            {
                self.downLoadTask.lbx_downLoadItem = nil;
                self.downLoadTask = nil;
            }
                break;
            default:
                break;
        }
    }
    
    if ( self.item && self.item.status != LBXDownloadStatus_Completed ) {
        [self startRequest];
        [self.downLoadTask resume];
    }
}

- (void) cancel
{
    self.item = nil;
    
    if (self.downLoadTask) {
        
        switch (self.downLoadTask.state) {
            case NSURLSessionTaskStateRunning:
            {
                //及时将.lbx_downLoadItem设置为nil,测试发现 删除操作(就是cancel时) 在回调中判断 self.downLoadTask.lbx_downLoadItem == nil空偶现崩溃
                //这里早一点设置为空后，暂没有发现崩溃情况。
                self.downLoadTask.lbx_downLoadItem = nil;
                [self.downLoadTask cancel];
            }
                break;
            case NSURLSessionTaskStateSuspended:
            {
                self.downLoadTask.lbx_downLoadItem = nil;
                [self.downLoadTask cancel];
            }
                break;
            case NSURLSessionTaskStateCompleted:
                NSLog(@"NSURLSessionTaskStateCompleted");
                break;
            case NSURLSessionTaskStateCanceling:
                break;
            default:
                break;
        }
        self.downLoadTask.lbx_downLoadItem = nil;
        self.downLoadTask = nil;
    }
}
@end



